App.require(["matrix3"], function (matrix3) {
    var Matrix3 = matrix3.Matrix3;
    App.defineWidget("line", {
        render: function (ctx) {
            ctx.save();
            var style = this.style;
            ctx.globalAlpha = style.opacity;
            var shadowObj = App.Widget.strToShadow(style.shadow);
            if (shadowObj) {
                ctx.shadowOffsetX = shadowObj.x;
                ctx.shadowOffsetY = shadowObj.y;
                ctx.shadowBlur = shadowObj.blur;
                ctx.shadowColor = shadowObj.color;
            }
            if (Array.isArray(style.linedash) && style.linedash.length > 0) {
                ctx.setLineDash(style.linedash);
                ctx.lineDashOffset = style.linedashoffset;
            }
            ctx.translate(style.x, style.y);
            var transforms = App.Widget.strToTransform(style.transform);
            if (transforms) {
                for (var i = 0; i < transforms.length; i++) {
                    var tranObj = transforms[i];
                    ctx[tranObj.key].apply(ctx, tranObj.param);
                }
            }
            ctx.strokeStyle = style.stroke;
            ctx.linewidth = style.linewidth;
            ctx.beginPath();
            ctx.moveTo(style.x1, style.y1);
            ctx.lineTo(style.x2, style.y2);
            ctx.stroke();
            ctx.restore();
        },
        isPointIn: function (ctx, x, y) {
            var style = this.style;
            ctx.save();
            ctx.translate(style.x1, style.y1);
            var deltaX = style.x2 - style.x1, deltaY = style.y2 - style.y1,
                len = Math.sqrt(deltaX * deltaX + deltaY * deltaY);
            var rot = Math.atan2(deltaY, deltaX);
            ctx.rotate(rot);
            ctx.beginPath();
            ctx.rect(-10, -10, len + 20, 20);
            var isIn = ctx.isPointInPath(x, y);
            ctx.restore();
            return isIn;
        },
        style: {
            transform: [], 
            x: 0,
            y: 0,
            x1: 0,
            y1: 0,
            x2: 30, 
            y2: 50, 
            shadow: "0 0 0 black",
            stroke: "black",
            opacity: 1,
            linewidth: 1,
            linedash: [],
            linedashoffset: 0
        },
        get transform() {
            return this.style.transform;
        },
        set transform(val) {
            this.style.transform = val;
            this.getScene().nextRender();
        },
        get x() {
            return this.style.x;
        },
        set x(val) {
            this.style.x = val;
            this.getScene().nextRender();
        },
        get y() {
            return this.style.y;
        },
        set y(val) {
            this.style.y = val;
            this.getScene().nextRender();
        },
        get x1() {
            return this.style.x1;
        },
        set x1(val) {
            this.style.x1 = val;
            this.getScene().nextRender();
        },
        get y1() {
            return this.style.y1;
        },
        set y1(val) {
            this.style.y1 = val;
            this.getScene().nextRender();
        },
        get x2() {
            return this.style.x2;
        },
        set x2(val) {
            this.style.x2 = val;
            this.getScene().nextRender();
        },
        get y2() {
            return this.style.y2;
        },
        set y2(val) {
            this.style.y2 = val;
            this.getScene().nextRender();
        },
        set shadow(val) {
            this.style.shadow = val;
            this.getScene().nextRender();
        },
        get shadow() {
            return this.style.shadow;
        },
        get stroke() {
            return this.style.stroke;
        },
        set stroke(val) {
            this.style.stroke = val;
            this.getScene().nextRender();
        },
        get opacity() {
            return this.style.opacity;
        },
        set opacity(val) {
            this.style.opacity = val;
            this.getScene().nextRender();
        },
        get linewidth() {
            return this.style.linewidth;
        },
        set linewidth(val) {
            this.style.linewidth = val;
            this.getScene().nextRender();
        },
        get linedash() {
            return this.style.linedash;
        },
        set linedash(val) {
            this.style.linedash = val;
            this.getScene().nextRender();
        },
        get linedashoffset() {
            return this.style.linedashoffset;
        },
        set linedashoffset(val) {
            this.style.linedashoffset = val;
            this.getScene().nextRender();
        }
    })
})